package com.flashcash.solu.view.camera

import android.Manifest
import android.app.Activity
import android.content.Intent
import android.support.v7.app.AlertDialog
import android.text.TextUtils
import android.view.View
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import com.flashcash.kotlin.data.BasicAck
import com.flashcash.kotlin.face.DeltaHolder
import com.flashcash.kotlin.face.FaceDetectActivity
import com.flashcash.solu.R
import com.flashcash.solu.app.base.BaseFragment
import com.flashcash.solu.app.base.BaseFragmentView
import com.flashcash.solu.app.base.presenter.BaseFragmentPresenter
import com.flashcash.solu.app.base.presenter.BaseFragmentPresenterImpl
import com.flashcash.solu.common.EventCollection
import com.flashcash.solu.common.FieldParams
import com.flashcash.solu.common.TokenManager
import com.flashcash.solu.common.network.FileUploadApi
import com.flashcash.solu.common.network.ServiceGenerator
import com.flashcash.solu.enums.LoanType
import com.flashcash.solu.enums.PeriodType
import com.flashcash.solu.harvester.TraceSender
import com.flashcash.solu.harvester.uploadout.UploadUtils
import com.flashcash.solu.utils.CommonUtils
import com.flashcash.solu.view.MainActivity
import com.flashcash.solu.view.certification.CertifyActivity
import com.flashcash.solu.view.loan.LoanNormalFragment1Activity
import com.flashcash.solu.widget.MyProgressBar
import com.flashcash.solu.widget.selfdefdialog.DialogManager
import com.flashcash.solu.widget.xleotoast.XLeoToast
import com.hwangjr.rxbus.RxBus
import com.x.leo.apphelper.log.XLog
import com.x.leo.apphelper.utils.PermissionRequester
import okhttp3.MediaType
import okhttp3.MultipartBody
import okhttp3.RequestBody
import org.jetbrains.anko.find
import org.jetbrains.anko.sdk25.coroutines.onClick
import rx.Subscriber
import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers

/**
 * Created by XLEO on 2017/12/17.
 */
abstract class FaceDetectorFragment<T : FaceDetectorPresenter> : BaseFragment<T>(), FaceDetectorView {
    companion object {
        private val PERMISSION_REQUEST_CODE = 0x0101
        private val FACE_DETECT_REQUEST_CODE = 0x010F
    }

    private var progressDialog: MyProgressBar? = null

    fun showLoading() {
        progressDialog?.dismiss()
        if (progressDialog == null) {
            progressDialog = MyProgressBar(context)
        }
        progressDialog?.show()
    }

    fun dismissLoading() {
        progressDialog?.dismiss()
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == FACE_DETECT_REQUEST_CODE) {
            if (resultCode == Activity.RESULT_OK) {
                showLoading()
                submitButtonStateUpdate(false)
//                XLeoToast.showMessage("检测完成，准备上传大礼包")
                mPresenter.uploadFaces(DeltaHolder.instance.delta) // 上传大礼包
            } else {
                when (data) {
                    null -> XLeoToast.showMessage(R.string.detect_live_face_fail)
                    else -> XLeoToast.showMessage(data.extras.getString(FieldParams.LivenessExtras.FAILED_MSG))
                }
                XLeoToast.showMessage(R.string.detect_live_face_fail)
            }
        }
    }

    abstract fun submitButtonStateUpdate(active: Boolean)

    override fun showFaceDetectorDialog() {
        DialogManager.showDialog(context, R.layout.dialog_face_detect, { dialog ->
            dialog.find<Button>(R.id.btn_ok).onClick {
                dialog.dismiss()
                /*mPresenter.checkFaceIdAuth()*/
                checkRecordPermission()
            }
        })
    }

    /*override fun authOk() {
        activity?.runOnUiThread {
            dismissLoading()
            checkRecordPermission()
        }
    }*/

    private fun checkRecordPermission() {
        PermissionRequester().requestPermissions(activity!!, arrayOf(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE), PERMISSION_REQUEST_CODE, object : Subscriber<Map<String, Boolean>>() {
            override fun onCompleted() {}

            override fun onError(throwable: Throwable) {}

            override fun onNext(stringBooleanMap: Map<String, Boolean>?) {
                if (stringBooleanMap == null || stringBooleanMap.isEmpty() || stringBooleanMap.values.contains(false)) {
                    XLeoToast.showMessage(R.string.permission_denied)
                } else {
                    if (context?.applicationContext != null) {
                        startActivityForResult(Intent(context?.applicationContext, FaceDetectActivity::class.java), FACE_DETECT_REQUEST_CODE)
                    }
                }
            }
        })
    }

    /*override fun authFail() {
        activity?.runOnUiThread {
            dismissLoading()
            XLeoToast.showMessage(R.string.faceid_auth_failed)
        }
    }*/

    override fun uploadFacesError(throwable: Throwable) {
        DeltaHolder.instance.delta = null // 清除大礼包
        dismissLoading()
        submitButtonStateUpdate(true)
        XLeoToast.showMessage(R.string.faceid_detect_fail)
        XLog.e("" + throwable.message, throwable, 100)
        if (activity is CertifyActivity) {
            activity!!.finish()
        }
    }

    override fun uploadFacesSuccess() {
        DeltaHolder.instance.delta = null // 清除大礼包
        XLeoToast.showMessage(R.string.faceid_detect_success)
        baseActivity.runOnUiThread {
            dismissLoading()
            RxBus.get().post(EventCollection.GotoLoaning(null))
            RxBus.get().post(EventCollection.FinishLoanNormalFragment1Activity())
            activity!!.finish()
        }
    }

    override fun showErrorMessage(message: String?) {
        DeltaHolder.instance.delta = null // 清除大礼包
        dismissLoading()
        submitButtonStateUpdate(true)
        if (message != null) {
            baseActivity.runOnUiThread {
                if (isVisible) {
                    if (activity is LoanNormalFragment1Activity && message.contains("day")) {//提示过多少天才能再次申请的弹出框
                        val view = View.inflate(context, R.layout.dialog_loan_click_reject, null)
                        val buttonTv = view.findViewById<ImageView>(R.id.btn_result_failed)
                        val dialog = DialogManager.newDialog(context, view, false)
                        buttonTv.setOnClickListener {
                            dialog.dismiss()
                        }
                        val tv = view.findViewById<TextView>(R.id.message)
                        tv.text = message
                        //获取缓存好的市场app
                        CommonUtils.initMarketImage(view, context)
                        dialog.show()
                    } else {//提示活体检测失败
                        AlertDialog.Builder(this.context!!)
                                .setTitle(R.string.tips_title)
                                .setMessage(message)
                                .setCancelable(false)
                                .setPositiveButton(R.string.button_ok) { dialog, _ ->
                                    run {
                                        dialog?.dismiss()
                                        if (activity is CertifyActivity) {
                                            activity!!.finish()
                                        }
                                    }
                                }
                                .create()
                                .show()
                    }
                }
            }
        }
    }
}

interface FaceDetectorView : BaseFragmentView {
    fun uploadFacesError(throwable: Throwable)
    fun uploadFacesSuccess()
    /*fun authOk()
    fun authFail()*/
    fun showFaceDetectorDialog()

    fun showErrorMessage(message: String?)
}

open class FaceDetectorPreImpl : BaseFragmentPresenterImpl(), FaceDetectorPresenter {
    override fun uploadFaces(delta: String?) {
        if (TokenManager.getInstance().hasLogin()) {
            with(delta) {
                if (this == null) {
                    when {
                        isAttached -> (mView as FaceDetectorView).showErrorMessage(mView.baseActivity.applicationContext.getString(R.string.detect_live_face_fail))
                        else -> {
                        }
                    }
                } else {
                    val deltaP = generateTextPart(delta, "delta")
                    ServiceGenerator.createService(FileUploadApi::class.java).faceVerify(
                            LoanType.PAYDAY.name,
                            MainActivity.selectedTotalAmount.amount,
                            MainActivity.selectedTotalAmount.day,
                            PeriodType.D.name,
                            null,
                            null,
                            deltaP,
                            TraceSender.getAndroidID(mView.baseActivity.applicationContext),
                            MainActivity.selectedTotalAmount.productId,
                            TokenManager.getInstance().token).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(object : Subscriber<BasicAck>() {


                        override fun onNext(t: BasicAck) {
                            if (isAttached && TextUtils.equals(t.code, "SUCCESS")) {
                                (mView as FaceDetectorView).uploadFacesSuccess()

                                UploadUtils.startUploadingIfNeeded(t.data)
                            } else if (isAttached) {
                                (mView as FaceDetectorView).showErrorMessage(t.message)

                            }
                        }

                        override fun onCompleted() {}

                        override fun onError(e: Throwable) {
                            if (isAttached) {
                                (mView as FaceDetectorView).uploadFacesError(e)
                            }
                            UploadUtils.uploadException(e, "FaceDetectorPreImpl.uploadFaces.onError")
                        }
                    })

                }
            }
        } else {
            mView.toLogin()
        }

    }

    private fun generateTextPart(delta: String?, desc: String): MultipartBody.Part {
        return MultipartBody.Part.createFormData(desc, delta)
    }

    private fun generateFilePart(bestImage: ByteArray, fileName: String, desc: String): MultipartBody.Part {
        val mediaType = "application/octet-stream"
        val requestBody = RequestBody.create(MediaType.parse(mediaType), bestImage)
        return MultipartBody.Part.createFormData(desc, fileName, requestBody)
    }

    /*override fun checkFaceIdAuth() {
        var manager: Manager? = null
        var livenessLicenseManager: LivenessLicenseManager? = null
        if (Looper.myLooper() == Looper.getMainLooper()) {
            manager = Manager(mView.baseActivity)
            livenessLicenseManager = LivenessLicenseManager(mView.baseActivity)
        } else {
            if (isAttached) {
                mView.baseActivity.runOnUiThread {
                    manager = Manager(mView.baseActivity)
                    livenessLicenseManager = LivenessLicenseManager(mView.baseActivity)
                }
            }
        }
        Observable.create<Boolean> {
            if (isAttached && manager != null && livenessLicenseManager != null) {
                try {
                    manager!!.registerLicenseManager(livenessLicenseManager)
                    manager!!.takeLicenseFromNetwork(DeviceUuidFactory.getUUidString(mView.baseActivity))
                    if (livenessLicenseManager != null && livenessLicenseManager!!.checkCachedLicense() > 0) {
                        it.onNext(true)
                    } else {
                        it.onNext(false)
                    }
                } catch (t: Throwable) {
                    it.onError(t)
                } finally {
                    it.onCompleted()
                }
            } else {
                it.onError(RuntimeException("presenter has been detached"))
            }

        }.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(object : Subscriber<Boolean>() {
                    override fun onCompleted() {
                    }

                    override fun onError(p0: Throwable?) {
                        if (isAttached) {
                            (mView as FaceDetectorView).authFail()
                        }
                    }

                    override fun onNext(p0: Boolean?) {
                        if (isAttached) {
                            if (p0 == true) {
                                (mView as FaceDetectorView).authOk()
                            } else {
                                (mView as FaceDetectorView).authFail()
                            }
                        }
                    }
                })
    }*/
}

interface FaceDetectorPresenter : BaseFragmentPresenter {
    fun uploadFaces(delta: String?)
    /*fun checkFaceIdAuth()*/
}
